/*
  Copyright (c) 2011, Mikheev Rostislav
  Copyright (c) 2011, FreshFarsh team

  Steel Engine source code is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
/**
  core.cpp

  @author Mikheev Rostislav <hacenator@gmail.com>
  @date 23.03.2011
  @brief GUI Basic Class source code
*/

#include "gui/core.h"

namespace _STEEL_NAMESPACE {

GUILayer::GUILayer(const WindowManager *window)
  : _height(0),
  _width(0),
  _cursor(NULL),
  _font(NULL),
  _window(NULL),
  _draw_info(false)
{
  _window = const_cast<WindowManager *>(window);

  IMouseListener::Listen(window);
  IWindowListener::Listen(window);
}

GUILayer::GUILayer(const WindowManager *window, int width, int height)
  : _height(0),
  _width(0),
  _cursor(NULL),
  _font(NULL),
  _window(NULL),
  _draw_info(false)
{
  _window = const_cast<WindowManager *>(window);

  IMouseListener::Listen(window);
  IWindowListener::Listen(window);

  SetSize(width, height);
}

GUILayer::~GUILayer() {
  delete _font;
  delete _cursor;

  IMouseListener::StopListen();
  IWindowListener::StopListen();
}

void GUILayer::OnMouseMove(int x, int y) {
  GLdouble px, py, pz;
  gluUnProject(x,
               _viewport[3] - y,
               0,
               &_model_matrix.array[0],
               &_projection_matrix.array[0],
               &_viewport[0],
               &px,
               &py,
               &pz);

  _mouse_x = px;
  _mouse_y = py;
}

void GUILayer::OnKeyDown(int key) {
  //
}

void GUILayer::OnInit() {
  SetupView();

  glGetIntegerv(GL_VIEWPORT, &_viewport[0]);
  glGetDoublev(GL_PROJECTION_MATRIX, &_projection_matrix.array[0]);
  glGetDoublev(GL_MODELVIEW_MATRIX, &_model_matrix.array[0]);

  // crearte default font
  _font = new GUIFont("store/megapolis.ttf", 12);

  // create cursor
  _cursor = new Texture("store/textures/cursor.png");
}

void GUILayer::SetupView() {
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, _width, _height, 0, -1, 1); // Ortho2D
  //glViewport(0, 0, _width, _height);
}

void GUILayer::SetSize(int width, int height) {
  if (width == 0 || height == 0)
    RuntimeError() << "GUILayer::SetSize() Size can not be null.";

  _width = width;
  _height = height;
}

void GUILayer::OnDraw() {
  // set GUI projection
  SetupView();

  // Draw additional info
  if (_draw_info) {
    _font->Printf(0, 0, L"Engine version: %d.%d.%d.%d", STEEL_VERSION[0], STEEL_VERSION[1], STEEL_VERSION[2], STEEL_VERSION[3]);
    _font->Printf(0, 15, L"FPS: %d", _window->fps());
    _font->Printf(0, 30, L"Mouse Position: %d; %d", _mouse_x, _mouse_y);
  }

  // Draw cursor
  glColor4f(1, 1, 1, 1);
  glEnable(GL_TEXTURE_2D);
  _cursor->Bind();

  Rect cursor_rect(_mouse_y,
                   _mouse_x + _cursor->width() * 0.7,
                   _mouse_y + _cursor->height() * 0.7,
                   _mouse_x);

  Quad2D cursor_quad;
  cursor_quad = cursor_rect;

  glVertexPointer(3, GL_FLOAT, sizeof(Vertex2D), &cursor_quad.vertex[0].point);
  glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex2D), &cursor_quad.vertex[0].texture);

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glDrawArrays(GL_QUADS, 0, 4);

  glDisableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);


  /*glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glBegin(GL_QUADS);

    glTexCoord2f(0, 0);
    glVertex2f(_mouse_x, _mouse_y + _cursor->height() * 0.7);

    glTexCoord2f(1, 0);
    glVertex2f(_mouse_x + _cursor->width() * 0.7, _mouse_y + _cursor->height() * 0.7);

    glTexCoord2f(1, 1);
    glVertex2f(_mouse_x + _cursor->width() * 0.7, _mouse_y);

    glTexCoord2f(0, 1);
    glVertex2f(_mouse_x, _mouse_y);

  glEnd();*/

  /*GLfloat vertices[4][3];
  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(2, GL_FLOAT, 0, vertices);

  vertices[0][0] = 0.0f;
  vertices[0][1] = 100;

  vertices[1][0] = 100;
  vertices[1][1] = 100;

  vertices[2][0] = 100;
  vertices[2][1] = 0.0f;

  vertices[3][0] = 0.0f;
  vertices[3][1] = 0.0f;

  glDrawArrays(GL_QUADS, 0, 4);
  glDisableClientState(GL_VERTEX_ARRAY);*/
}


}
